import numpy as np
import cv2
import cv2.cv as cv
import csv,sys
import re
import os
#import stt
#import tts
from datetime import datetime
from time import sleep

global max_id
img_count = 18			# Images Saved (for New user saving)
UCount = 0			# Unidentified Usr Count
uid = 0				# UID of person
NAME = ''			# Name of person
PING = 0
SPEAK = False
FLAG =0
WFlag = 0			# Used to tell if Unidentified User is real
CurTime = datetime.now()	# Current Time Global

def detect(img, cascade_fn='lbpcascade_frontalface.xml',
           scaleFactor=1.1, minNeighbors=3, minSize=(80, 80),
           flags=cv.CV_HAAR_SCALE_IMAGE):

    cascade = cv2.CascadeClassifier(cascade_fn)
    rects = cascade.detectMultiScale(img, scaleFactor=scaleFactor,
                                     minNeighbors=minNeighbors,
                                     minSize=minSize, flags=flags)
    if len(rects) == 0:
        return []
    rects[:, 2:] += rects[:, :2]
    return rects

def read_images(filename):
	image,label,names = [],[],[]
	with open(filename,'rb') as f:
		reader = csv.reader(f, delimiter=';')
		try:
			for row in reader:
				im = cv2.imread(row[0], cv2.IMREAD_GRAYSCALE)
				image.append(np.asarray(im, dtype=np.uint8))
				label.append(np.asarray(row[1], dtype=np.int32))
				max_id = (int)(row[1])
				m = re.search(r"\/([A-Za-z0-9_]+)\/", row[0])
				if names == [] or (m.group(1) != names[-1]):
					names.append(m.group(1))
		except csv.Error as e:
			sys.exit('file %s,line %d: %s' % (filename,reader.line_num,e))
		return image,label,names

def save_image(n_uid,n_name,count,img):
	raw_path = 'data/'+ n_name
	imPath = str(raw_path)+'/'+str(count)+'.pgm'
	fd = open('humia.csv','a')
	fd.write(imPath + ';'+str(n_uid)+"\n")
	fd.close()
	cv2.imwrite(imPath,img)
	return

#if __name__ == '__main__':
def facemain():
	global FLAG
    	global NAME
	UCount = 0			# Unidentified Usr Count
	SPEAK = False
	WFlag = 0			# Used to tell if Unidentified User is real
	CurTime = datetime.now()	# Current Time Global
	max_id = 0
	model = cv2.createLBPHFaceRecognizer()
	image,label,names = read_images('humia.csv')
	model.train(np.asarray(image), np.asarray(label))
		#model.load("LBPHfaces_alt.yml")

	cap = cv2.VideoCapture(3)
	# Init dummy image
	b, large = cap.read()
	while(True):
		# Capture frame-by-frame
		ret, frame = cap.read()
		original = frame.copy()

		# Convert to Greyscale, equalize
		gray = cv2.cvtColor(frame, cv.CV_BGR2GRAY)
		gray = cv2.equalizeHist(gray)
	
		# Detect Faces from image
		rects = detect(gray)
		color = (0, 255, 0)
		
		y2p,x2p = 0,0
		delta = datetime.now() - CurTime
		if WFlag == 1 and (float)(delta.total_seconds()) > 1.8 and UCount > 20 and PING == 1 and SPEAK == False:
			WFlag,UCount = 0,0
			FLAG = 1
			print "I see you"
		for x1, y1, x2, y2 in rects:
			crop_img = gray[y1:y2, x1:x2]
			if (y2*x2) > y2p *x2p:
				y2p = y2
				x2p = x2
				large = crop_img

			[p_label, p_confidence] = model.predict(crop_img)
			#box_text = names[p_label-1]
			box_text = "Predicted label = %d (confidence=%.2f)" % (p_label, p_confidence)

			# If Confidence > threshold start wait timer (WFlag)
			# WFlag is used to tell if a newly detected face is an error, or a real person
			# We wait 3 seconds and count how many time an unreocgnized face was found
			if (p_confidence < 45 and WFlag == 0):
				CurTime= datetime.now()
				WFlag = 1
				UCount += 1
				NAME = names[p_label-1]
			elif(p_confidence <45 and WFlag == 1):
				UCount += 1
			elif(p_confidence >65):
				box_text = "Person"

			cv2.rectangle(original, (x1, y1), (x2, y2), color, 2)
			cv2.putText(original, box_text, (x1, y1-5), cv2.FONT_HERSHEY_PLAIN, 1, color, 2)
		
		if (int)(delta.total_seconds()) > 12:
			WFlag = 0
		# Display the resulting frame
		cv2.imshow('Face Recognizer',original)

		# Detect if 'q' Pressed (quit)
		if cv2.waitKey(15) & 0xFF == ord('q'):
			#model.save("LBPHfaces_alt.yml")
			break
		
	# When everything done, release the capture
	cap.release()
	cv2.destroyAllWindows()
